;<134-TENEX>LINEPR.MAC;6 1-Jul-77 16:00:28 EDIT BY LYNCH ;<134-TENEX>LINEPR.MAC;5 17-Jun-77 09:09:55 EDIT BY LYNCH ; FIXED TO RUN WITHOUT PHYSICAL DEVICE ONLINE ANYMORE. ;<134-TENEX>LINEPR.MAC;4 17-FEB-76 11:40:20 EDIT BY UNTULIS ;ADDED EXTERNS ;<133-TENEX>LINEPR.MAC;11 12-DEC-75 13:46:55 EDIT BY UNTULIS ;DISABLE DEFAULT ACCOUNT FOR LPT. FILES ;<133-TENEX>LINEPR.MAC;10 17-JUN-75 14:10:24 EDIT BY UNTULIS ;<133-TENEX>LINEPR.MAC;9 17-JUN-75 13:45:06 EDIT BY UNTULIS ;<133-TENEX>LINEPR.MAC;8 15-JUN-75 22:33:35 EDIT BY UNTULIS ;<133-TENEX>LINEPR.MAC;10 6-MAR-75 09:16:14 EDIT BY UNTULIS ;<133-TENEX>LINEPR.MAC;9 2-MAR-75 15:22:33 EDIT BY UNTULIS ;<133-TENEX>LINEPR.MAC;5 28-FEB-75 09:43:31 EDIT BY UNTULIS ;ADD CODE FOR PAGE OUTPUT TO PRINTER ;<133-TENEX>LINEPR.MAC;3 13-FEB-75 19:53:36 EDIT BY LYNCH ; MADE PRINTER BUFFER WHOLE PAGE INSTEAD OF HALF PAGE. ;LINEPR.AIC;1 27-DEC-73 15:18:27 EDIT BY LYNCH ;LINEPR.AIC;4 19-DEC-73 14:19:47 EDIT BY LYNCH ;LINEPR.AIC;3 12-NOV-73 23:49:58 EDIT BY KREMERS ;FIXED SO PRINTR CAN RUN AS AUTO JOB ;LINEPR.MAC;6 8-AUG-73 5:45:07 EDIT BY KREMERS ;LINEPR.MAC;5 8-AUG-73 5:33:38 EDIT BY KREMERS ;LINEPR.MAC;4 8-AUG-73 5:25:50 EDIT BY KREMERS ;LINEPR.MAC;3 8-AUG-73 5:09:12 EDIT BY KREMERS SEARCH PROLOG,STENEX TITLE LINEPR IFDEF LPTN,< ; LAST ALTERED BY P.H.LIPMAN 8 MAY 72 10:17AM ;ORIGINAL SRI-AIC 1.29 LINEPR.FAI MODIFIED TO WORK WITH 1.31 ; Externally defined symbols EXTERN BUGCHK,BUGHLT,CAPENB,MRETN EXTERN DISLE ; Disms til arg .le. 0 EXTERN JOBDIR,UNLCKF,PBYTSZ,PBYTPO,MULKPG EXTERN CPOPJ,LCKTST,ASGJFR,RELFRE,MLKPG,SKPRET,GDIRST,DISL,FPTA INTERN LPTINI IFDEF LPTDVF,< EXTERN LPTCHR ; Return from line printer interrupt EXTERN LPTTIM ; Lpt check timer ; Entries to this part INTERN LPTSV,LPTRST ; Interrupt routine INTERN LPTCHK ; Check routine ; Parameters and fixed core locations LPT=124 ; Line printer device LPTWID==^D132 ; NO. OF CHARS ON A PRINTER LINE PI==4 IOS=6 HDBLNK==4 ; NO. OF BLANKS AFTER EACH HEADER NAME LPTCLR==1B25 ; CLEAR PRINTER LPTBSY==1B28 ; BUSY BIT LPTDON==1B29 ; DONE BIT LPTERR==1B27 ; LINE PRINTER OFF LINE LPTBOT==10*LPTCHN+LPTCHN ; BOTH INTERRUPTS FOR LPT LPTFF==1 ;NUMBER OF FORMFEEDS OUTPUT TO LP1 WHEN CLOSED. LS(LPTINR) ; Return address in interrupt routine LPSTKL==10 ; Interrupt stack length LS(LPSTK,LPSTKL) ; Stack for interrupt routine LS(LPTSTS) ; Status word LS(LPTRLP) ; Real core address for line printer LS(LPTCNT) ; Buffer counter LS(LPTJOB) ; Job of last lpt opener LS(LPTCLS) ; SWITCH TO TURN ON CLOCK STUFF LS(LPTCCW) ; WORD FOR INTERRUPT ROUTINE TO DO "BLKO" LS(LPTCKT) ; AMOUNT OF TIME TO WAIT BETWEEN CALLS TO LPTCHK NRP(LPTBUF,2000) > LS(LPTLCK) ; Lock on opening lpt IFDEF LPTDVF,< FLG(ALTP,L,IOS,400000) ; 0 IF FILLING FIRST BUFFER, 1 IF FILLING SECOND FLG(ALTI,L,IOS,200000) FLG(OUERR,L,IOS,100000) ; OUTPUT ERROR FLG(OPN,L,IOS,040000) ;LINE PRINTER OPEN FLG(FSTBF,L,IOS,020000) ; FIRST BUFFER OF FILE ISSUE RESET FLG(LAST,L,IOS,010000) ; LAST WORD SENT > ; Line printer dispatch table USE RESPC SPOOLP: 1 ; .GT. 0 IF SPOOLING USE SWAPPC SPLDTB:: LPTDTB::CPOPJ ;SET DIRECTORY CPOPJ ; Name lookup CPOPJ ; Extension CPOPJ ; Version CPOPJ ; Protection insertion CPOPJ ; Account CPOPJ LPTOPN CPOPJ LPTSQO ; Output LPTCLZ CPOPJ ; Rename CPOPJ ; Delete CPOPJ IFDEF LPTDVF,< LPTDMP ; DUMP ENTIRE PAGE TO PRINTER > IFNDEF LPTDVF,< CPOPJ > CPOPJ ; Mount CPOPJ ; Dismount CPOPJ ; Initialize directory CPOPJ ; Mtape CPOPJ ; Get status CPOPJ ; Set status ; Initialize line printer USE RESPC LPTINI: IFDEF LPTDVF,< SETZM LPTSTS SETOM LPTCNT> SETOM LPTLCK POPJ P, LPTRST: IFDEF LPTDVF,< MOVE IOS,LPTSTS SKIPL LPTCNT JRST LPTSTR> POPJ P, USE SWAPPC ; Open line printer LPTOPN: IFDEF LPTSPL,< HLRZ A,FILDDN(JFN) MOVE A,1(A) SKIPE SPOOLP ; IF NOT SPOOLING CAME A,[ASCII /LPT/] ; OR IF LP1 JRST LP1OPN ; THEN DON'T SPOOL MOVEI A,400000 PUSH P,CAPENB ; Save current capenb IORM A,CAPENB ; Give ourselves wheel status LPTOPA: MOVEI B,8 PUSHJ P,ASGJFR ; Get some job storage JRST LPTOPC ; Fail to spool PUSH P,A HRLI A,() HRROI B,[ASCIZ /LPT./] SETZ C, SOUT MOVE B,JOBNO HRRZ B,JOBDIR(B) DIRST BUG(HLT,) ; HRROI B,[ASCIZ /;ASYSTEM/] ; SOUT DISABLE TO ALLOW SPOOLER TO CHARGE USER ; FOR PRINT TIME LPTOPD: GTAD ; Use time of day as version ANDI A,177777 XOR A,JFN ; Alter for differing jfn's HRLI A,(1B0!1B1!1B8!1B17) MOVE B,0(P) HRLI B,() GTJFN JRST [ POP P,B MOVEI A,JSBFRE PUSHJ P,RELFRE JRST LPTOPC] POP P,B PUSH P,A MOVEI A,JSBFRE PUSHJ P,RELFRE MOVE A,0(P) MOVE B,[XWD 70000,100000] OPENF JRST [ POP P,A RLJFN JFCL JRST LPTOPC] NOINT PUSHJ P,UNLCKF POP P,A POP P,CAPENB MOVE B,JFN LSH B,-SJFN SWJFN RLJFN JFCL MOVE A,MPP AOS (A) JRST MRETN LPTOPC: POP P,CAPENB LP1OPN: IFNDEF LPTDVF,< MOVEI A,OPNX9 POPJ P, LPTSQO: LPTCLZ: BUG(CHK,) >> ; Close of ifdef at lptopn and lp1opn ; Open line printer IFDEF LPTDVF,< LOCK LPTLCK, MOVE IOS,LPTSTS CONSZ LPT,LPTERR ;SKIP IF ON LINE JRST LPTBS1 ;CALL IT BUSY, EVEN THOUGH OFF LINE TEST(OE,OPN) JRST LPTBS1 ;BUSY LDB A,PBYTSZ ;USER SPECIFIED BYTE SIZE CAIE A,7 ;MUST BE 7 FOR LPT JRST [ UNLOCK LPTLCK MOVEI A,SFBSX2 POPJ P, ] TLZ IOS,ALTP!ALTI!OUERR!LAST TEST(O,FSTBF) MOVEM IOS,LPTSTS SETOM LPTCNT ; Lpt idle SETZM LPTCLS MOVEI A,LPTBUF MOVES (A) PUSHJ P,FPTA ; Get ptn.pn for buffer PUSHJ P,MLKPG ; Lock the page MOVEI A,LPTBUF+1000 ; POINT TO ALTERNATE BUFFER PAGE MOVES (A) ; TOUCH IT PUSHJ P,FPTA PUSHJ P,MLKPG MOVE A,[XWD -1000,LPTBUF] MOVEM A,LPTRLP ; Save MOVEI A,0 DPB A,PBYTPO ; Position MOVEI A,LPTBUF-1 HRRM A,FILBYT(JFN) ; Point to buffer MOVEI A,1000*5 MOVEM A,FILBYN(JFN) ; Character count TEST(Z,WNDF) UNLOCK LPTLCK MOVE A,JOBNO HRRZ A,JOBDIR(A) ;IS THIS (I.E. LINE PRINTER AUTO JOB) ? CAIE 1,1 ;DIRNUM FOR IS AND ALWAYS WILL BE 1 JRST LPTHDR ;NO, PRINT HEADER JRST SKPRET ;AND RETURN SUCCESSFULLY LPTBS1: UNLOCK LPTLCK LPTBS2: MOVEI A,OPNX9 POPJ P, ;NO SKIP RETURN LPTHDR: MOVE A,JOBNO HRRZ A,JOBDIR(A) ; Get login directory number PUSHJ P,GDIRST ; Get name string location JRST [ JSR BUGCHK ;BAD DIRECTORY NO. POPJ P, ] UNLOCK DIRLCK ; No need to keep directory locked OKINT HRLI A,() ; Make it a byte pointer PUSH P,A ; Save on stack MOVEI C,HDBLNK-1 ;4 BLANKS AT END OF EACH NAME AOS C ILDB B,A JUMPN B,.-2 ;COUNT CHARS IN NAME MOVEI A,LPTWID ;WIDTH OF PRINTER IN CHARS IDIV A,C ;NO. OF NAMES THAT WILL FIT PUSH P,A ;SAVE ON STACK PUSH P,[^D10] ; Number of lines of ident LPTHD1: PUSH P,-1(P) ; Number of names per line LPTHD2: PUSH P,-3(P) ; Copy byte pointer to stack LPTHD3: ILDB A,(P) ; Get byte from string JUMPE A,LPTHD4 ; End PUSHJ P,@BOUTD(DEV) ; Print it JRST LPTHD3 ; And loop thru all characters LPTHD4: MOVEI A,HDBLNK MOVEM A,(P) ;CLOBBER SPENT BYTE PTR LPTHD5: MOVEI A," " PUSHJ P,@BOUTD(DEV) SOSLE (P) JRST LPTHD5 POP P,A ;FLUSH CLOBBERED SPENT BYTE PTR SOSLE (P) ; Count names per line JRST LPTHD2 ; Repeat POP P,A ; Flush spent count MOVEI A,37 PUSHJ P,@BOUTD(DEV) ; End line with eol SOSLE (P) ; Count lines of heading JRST LPTHD1 ; Repeat for each line POP P,A ; Flush spent count POP P,A ;FLUSH SAVED NAME COUNT POP P,A ; Flush saved byte pointer MOVEI A,14 PUSHJ P,@BOUTD(DEV) JRST SKPRET ; Close line printer LPTCLZ: IFN LPTFF, LPTCL0: SETZ A, PUSHJ P,LPTSQO ;FILL BUFFER WITH NULLS TEST(NN,WNDF) ; Wndf is set when full JRST LPTCL0 MOVEI 1,LPTCNT PUSHJ P,DISL ; Wait for line printer to stop MOVEI A,LPTBUF PUSHJ P,FPTA PUSHJ P,MULKPG MOVEI A,LPTBUF+1000 ; ALSO RELEASE SECOND PAGE PUSHJ P,FPTA PUSHJ P,MULKPG MOVSI IOS,OPN ANDCAM IOS,LPTSTS JRST SKPRET ; DUMP ONE PAGE TO PRINTER ; ASSUMPTIONS ; 1)FIRST DATA CHARACTER ON PAGE BOUNDRY ; 2)CHARACTER COUNT APPEARS IN WORD BEFORE FIRST DATA WORD ; AC2= IOWD -1001,CHARACTER COUNT WORD ADDRESS LPTDMP: UMOVE A,2 ;GET COMMAND LIST ADDRESS UMOVE B,0(A) ;GET ADDRESS OF BYTE COUNT UMOVE C,0(B) ;GET BYTE COUNT HRRI D,1(B) ;ADDRESS OF DATA HRLI D,440700 OUTLP: XCTBU[ILDB A,D] ;GET BYTE INTO A PUSHJ P,LPTSQ1 ;OUTPUT BYTE SOJG C,OUTLP POPJ P, ; SEQUENTIAL OUTPUT ROUTINE LPTSQO: ANDI A,177 LPTSQ1: CAIN A,37 ;CONVERT EOL MOVEI A,12 ;TO LF TEST(NE,WNDF) PUSHJ P,BUFWAT IDPB A,FILBYT(JFN) SOSLE FILBYN(JFN) POPJ P, AOSN LPTCNT ;IF COUNT WAS -1 PUSHJ P,LPTSTR ;START LPT, OTHERWISE IT WAS GOING MOVSI IOS,ALTP XORB IOS,LPTSTS MOVEI B,LPTBUF-1 TEST(NN,ALTP) HRRM B,FILBYT(JFN) MOVEI B,1000*5 MOVEM B,FILBYN(JFN) TEST(O,WNDF) POPJ P, BUFWAT: PUSH P,1 MOVEI 1,LPTCNT SKIPLE (1) ;IF LPTCNT ^D1, THEN BOTH BUFFERS FULL PUSHJ P,DISLE ;WAIT FOR BUFFER TEST(Z,WNDF) POP P,1 POPJ P, USE RESPC ; Line printer interrupt LPTSV: XWD LPTINR,.+1 CONSO LPT,LPTDON+LPTERR JRST @LPTINR CONSO LPT,77 ;IS PRINTER RUNNING JRST @LPTINR ;NO, NOT MY INTERRUPT MOVEM P,LPSTK MOVE P,[IOWD LPSTKL-1,LPSTK+1] PUSH P,IOS MOVE IOS,LPTSTS CONSZ LPT,LPTERR JRST LPTER ;ERROR TEST (ZE,LAST) JRST LPTNXT ;NO MORE DATA IN THIS BUFFER LPTOUT: MOVE A,LPTCCW DATAO LPT,0(A) ;OUTPUT NEXT DATA WOR AOBJP A,LPTLST ;LAST WORD IN BUFFER MOVEM A,LPTCCW LPTXIT: POP P,IOS POP P,P JRST LPTCHR ;RETURN FROM INTERRUPT ;NOTE THAT LAST WORD OF BUFFER WAS TRANSMITTED LPTLST: TEST (O,LAST) ;SET LAST FLAG MOVEM IOS,LPTSTS JRST LPTXIT ;BUFFER COMPLETE, SEE IF MORE TO DO LPTNXT: TEST (C,ALTI) ;TOGGLE INTERRUPT BUFFERS MOVEM IOS,LPTSTS SOSL LPTCNT ;ANOTHER BUFFER READY? JRST LPTCON CONO LPT,0 JRST LPTXIT LPTER: CONO LPT,0 ;SHUT OFF PRINTER SETOM LPTCLS MOVEI A,^D2000 ;SHORT TIME BETWEEN MOVEM A,LPTCKT ;LPTCHK'S WHILE PRINTER IS OFF LINE MOVEM A,LPTTIM JRST LPTXIT LPTCHK: MOVE A,LPTCKT MOVEM A,LPTTIM SKIPN LPTCLS POPJ P, ;NEED TO TRY AND RESTART PRINTER, SEE IF ERROR STILL SET CONSZ LPT,LPTERR POPJ P, ;STILL NOT READY SETZM LPTCLS MOVSI A,(1B1) ;RESET INTERVAL BETWEEN MOVEM A,LPTCKT ;LPTCHK'S TO VERY LARGE TIME JRST LPTST1 ;START IT UP AGAIN LPTSET: PUSH P,A MOVE IOS,LPTSTS MOVE A,LPTRLP TEST(NE,ALTI) ADDI A,1000 MOVEM A,LPTCCW POP P,A POPJ P, LPTSTR: PUSHJ P,LPTSET ;RETURNS WITH IOS SET UP TEST (ZN,FSTBF) ;SKIP IF THIS IS FIRST BUFFER OUT ;SINCE OPENING JRST LPTST1 MOVEM IOS,LPTSTS ;NO INTERRUPTS COULD INTERFERE CONO LPT,LPTBOT+LPTCLR ;ISSUE CLEAR AS WELL, WILL INTERRUPT ;WHEN READY POPJ P, LPTST1: CONO LPT,LPTBOT DATAO LPT,[0] POPJ P, LPTCON: PUSHJ P,LPTSET JRST LPTOUT > ;END OF IFDEF JUST BELOW LP1OPN USE SWAPPC END >